<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            padding-bottom: 800px;
            padding-left: 30px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div>
            <h4>生命周期</h4>
            <ul>
                <li>生命周期:一段代码从运行到结束的时间线</li>
                <li>
                    钩子函数(hook):是被集成在代码运行过程中,特定节点的方法
                    <ol>
                        <li>
                            在实例初始化之后，数据观测 和 事件配置之前被调用。 <br>
                            beforeCreate:function(){},
                        </li>
                        <li>
                            在实例创建完成后被立即调用 <br>
                            created:function(){},
                        </li>
                        <li>
                            在挂载开始之前被调用：相关的 render 函数首次被调用。 <br>
                            beforeMount:function(){},
                        </li>
                        <li>
                            el 被新创建的 vm.$el 替换，并挂载到实例上去之后调用该钩子 <br>
                            mounted:function(){},
                        </li>
                        <li>
                            数据更新时调用，发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM <br>
                            beforeUpdate:function(){},
                        </li>
                        <li>
                            由于数据更改导致的虚拟 DOM 重新渲染和打补丁，在这之后会调用该钩子。 <br>
                            updated:function(){},
                        </li>
                        <li>
                            实例销毁之前调用。在这一步，实例仍然完全可用。 <br>
                            vue3: beforeUnmount:function(){}, <br>
                            vue2: beforeDestroy:function(){},
                        </li>
                        <li>
                            Vue 实例销毁后调用。调用后，Vue 实例指示的所有东西都会解绑定，所有的事件监听器会被移除 <br>
                            vue3: unmounted:function(){}, <br>
                            vue2: destroyed:function(){},
                        </li>
                    </ol>
                </li>
            </ul>
            <p ref="msg">msg:{{ msg }}</p>
            <input type="text" v-model="msg">
            <input type="button" value="setMsg()" @click="setMsg()">
            <p>info:{{ info }}</p>
            <input type="text" v-model="info">
            <hr>
            <input type="button" value="开启计时器" @click="starTime()">
            <br>
            <input type="button" value="销毁实例" @click="unmountFun()">
        </div>
    </div>
    <script type="module">
        // 加载 Vue3 的ESM 模块文件
        import { createApp } from "../assets/vue3/vue.esm-browser.js"
        const app = createApp({
            data() {
                return {
                    msg:"",
                    info:"info"
                }
            },
            watch: {
                msg() {
                  console.log("msg watch")  
                }
            },
            methods: {
                setMsg() {
                    this.msg = Math.random();
                    this.$nextTick(()=>{
                        console.log("msg对应的页面元素更新")
                    })
                },
                unmountFun(){
                    app.unmount();
                },
                starTime(){
                    this.$timer = setInterval(()=>{
                        console.log(1)
                    },1000)
                }
            },
            beforeCreate () {
                console.group("beforeCreate==>vue实例创建完成,环境配置构建完成")
                console.log("this:",this)
                console.log("$options:",this.$options)
                console.log("$data({}):",this.$data)
                console.log("this.msg(undefined):",this.msg)
                // this.msg = "aaaa"
                console.log("$el(null):",this.$el)
                console.groupEnd()
            },
            created () {
                /*
                    项目开发中，通过该生命周期函数完成页面加载时的初始化数据获取操作
                    项目开发过程中，一般会将相应式数据的初始化异步请求放置在 created 生命周期中，目的是为了兼容 SSR
                        => SSR - server side render 服务端渲染
                */
                this.msg = "msg变量"
                console.group("created==>vue响应式数据仓库创建完成(劫持数据已完成构建)")
                console.log("$data({ msg:'msg变量' }):",this.$data)
                console.log("this.msg(msg变量):",this.msg)
                console.log("$el(null):",this.$el)
                console.groupEnd()
            },
            beforeMount () {
                console.group("beforeMount==>完成模板加载,虚拟DOM生成,关联页面构建")
                console.log("$el(null):",this.$el) // 构建的虚拟DOM和对应的vue环境DOM尚未完成页面显示操作(挂载)
                console.log("this.$refs({})",this.$refs)
                console.groupEnd()
            },
            mounted () {
                  /*
                    项目开发中，通过该生命周期函数完成页面DOM相关的三方操作
                */
                console.group("mounted==>页面完成vue实例元素结构的显示操作")
                console.log("$el(DOM):",this.$el)
                console.log("this.$refs({ msg:…… })",this.$refs)
                console.groupEnd()
            },
            beforeUpdate () {
                console.group("beforeUpdate==>")
                console.log("this.msg(修改后的新数据):",this.msg)
                console.log("this.$refs.msg.textContent",this.$refs.msg.textContent)
                console.groupEnd()
            },
            updated () {
                console.group("updated==>")
                console.log("this.msg(修改后的新数据):",this.msg)
                console.log("this.$refs.msg.textContent",this.$refs.msg.textContent)
                console.groupEnd()
            },
            beforeUnmount(){
                // 用于关闭或销毁一些不受vue控制JS功能或方法
                clearInterval(this.$timer)
                console.group("beforeUnmount==>")
                console.groupEnd()
            },
            unmounted(){
                console.group("unmounted==>")
                console.groupEnd()
            }
        });
        
        app.mount("#app")
    </script>
</body>

</html>